/* @flow */

/**
 * 模板编译
 * 用户写的模板 --> 模板编译 --> render函数 --> Vnode  --> patch  --> 视图  
 * 模板编译过程就是把用户写的模板经过一系列处理最终生成render函数的过程。
 * 把字符串转化为AST
 *  模板解析阶段：将一堆模板字符串用正则等方式解析成抽象语法树AST；
    优化阶段：遍历AST，找出其中的静态节点，并打上标记；
    代码生成阶段：将AST转换成渲染函数；

    这三个阶段在源码中分别对应三个模块，下面给出三个模块的源代码在源码中的路径：

    模板解析阶段——解析器——源码路径：src/compiler/parser/index.js;
    优化阶段——优化器——源码路径：src/compiler/optimizer.js;
    代码生成阶段——代码生成器——源码路径：src/compiler/codegen/index.js;
 * 
 */
import { parse } from "./parser/index";
import { optimize } from "./optimizer";
import { generate } from "./codegen/index";
import { createCompilerCreator } from "./create-compiler";

// `createCompilerCreator` allows creating compilers that use alternative
// parser/optimizer/codegen, e.g the SSR optimizing compiler.
// Here we just export a default compiler using the default parts.
export const createCompiler = createCompilerCreator(function baseCompile(
  template: string,
  options: CompilerOptions
): CompiledResult {
  // 模板解析阶段：用正则等方式解析 template 模板中的指令、class、style等数据，形成AST
  debugger;
  const ast = parse(template.trim(), options);
  /**
 * ast里面带事件的标签
 * events {
    "click": {
        "value": "onclick",
        "dynamic": false,
        "start": 40,
        "end": 61,
        "modifiers": {
            "stop": true
            }
        }
    }
 * 
 * 
 * 
 */

  debugger;
  if (options.optimize !== false) {
    // 优化阶段：遍历AST，找出其中的静态节点，并打上标记，找出其中的静态根节点，并打上标记，这是 Vue 在编译过程中的一处优化，挡在进行patch 的过程中， DOM-Diff 算法会直接跳过静态节点，从而减少了比较的过程，优化了 patch 的性能。
    optimize(ast, options);
  }
  // 代码生成阶段：将AST转换成渲染函数； 将 AST 转化成 render函数字符串的过程，得到结果是 render函数的字符串以及 staticRenderFns 字符串。
  const code = generate(ast, options);
  //最终返回了抽象语法树( ast )，渲染函数( render )，静态渲染函数( staticRenderFns )，且render 的值为code.render，staticRenderFns 的值为code.staticRenderFns，
  //也就是说通过 generate处理 ast之后得到的返回值 code 是一个对象。
  return { ast, render: code.render, staticRenderFns: code.staticRenderFns };
});
